package edu.gatech.gro.utils;

import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.util.Log;
import edu.gatech.gro.model.AbstractObject;
import edu.gatech.gro.model.Item;
import edu.gatech.gro.model.ListGroup;
import edu.gatech.gro.model.ListItem;
import edu.gatech.gro.model.NamedList;
import edu.gatech.gro.model.User;

public class JSONHelper {

	private static final String TAG = "JSON_HELPER";

	public static JSONArray getJSONUsers(List<User> users, Context ctx) {
		JSONArray arr = new JSONArray();
		if (users != null) {
			for (User u : users) {
				arr.put(getJSON(u, ctx));
			}
		}
		return arr;
	}

	public static JSONObject getJSON(User user) {
		return getJSON(user, null);
	}

	public static JSONObject getJSON(User user, Context ctx) {
		JSONObject json = getJSONAbstract(user);
		if (user != null) {
			try {
				json.put("username", user.getUsername());
				json.put("usernameClean", user.getUsernameClean());
				json.put("email", user.getEmail());
				json.put("password", user.getPassword());
				if (ctx != null) {
					json.put("lists", getJSONLists(user.getLists(ctx), ctx));
				}
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}

	public static JSONArray getJSONLists(List<NamedList> lists, Context ctx) {
		JSONArray arr = new JSONArray();
		if (lists != null) {
			for (NamedList l : lists) {
				arr.put(getJSON(l, ctx));
			}
		}
		return arr;
	}

	public static JSONObject getJSON(NamedList namedList) {
		return getJSON(namedList, null);
	}

	public static JSONObject getJSON(NamedList namedList, Context ctx) {
		JSONObject json = getJSONAbstract(namedList);
		if (namedList != null) {
			try {
				json.put("name", namedList.getName());
				json.put("nameClean", namedList.getNameClean());
				if (ctx != null) {
					json.put("groups", getJSONItemGroups(namedList.getItemGroups(ctx), ctx));
				}
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}

	public static JSONArray getJSONItemGroups(List<ListGroup> groups, Context ctx) {
		JSONArray arr = new JSONArray();
		if (groups != null) {
			for (ListGroup lg : groups) {
				arr.put(getJSON(lg, ctx));
			}
		}
		return arr;
	}

	public static JSONObject getJSON(ListGroup group) {
		return getJSON(group, null);
	}

	public static JSONObject getJSON(ListGroup group, Context ctx) {
		JSONObject json = getJSONAbstract(group);
		if (group != null) {
			try {
				json.put("name", group.getName());
				json.put("nameClean", group.getNameClean());
				if (ctx != null) {
					json.put("items", getJSONItems(group.getItems()));
				}
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}

	public static JSONArray getJSONItems(List<Item> items) {
		JSONArray arr = new JSONArray();
		if (items != null) {
			for (Item li : items) {
				arr.put(getJSON((ListItem) li));
			}
		}
		return arr;
	}

	/**
	 * Returns a JSON object modelising the NamedListItem object.
	 * 
	 * @param namedList
	 * @param item
	 * @return A NamedListItem
	 */
	public static JSONObject getJSON(ListItem item) {
		JSONObject json = getJSONAbstract(item);
		if (item != null) {
			try {
				json.put("checked", item.isChecked());
				json.put("quantity", item.getQuantity());
				json.put("currentQuantity", item.getCurrentQuantity());
				json.put("namedListId", item.getNamedListId());
				json.put("itemId", item.getId());
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}

	public static JSONObject getJSONItem(Item item) {
		JSONObject json = getJSONAbstract(item);
		if (item != null) {
			try {
				json.put("itemTypeId", item.getItemTypeId());
				json.put("groceryStoreId", item.getGroceryStoreId());
				json.put("name", item.getName());
				json.put("nameClean", item.getNameClean());
				json.put("barCode", item.getId());
				json.put("price", item.getPrice());
				json.put("currency", item.getCurrency());
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}

	public static JSONObject getJSON(int namedListId, ListItem item) {
		JSONObject json = getJSONAbstract(item);
		if (item != null) {
			try {
				json.put("checked", item.isChecked());
				json.put("quantity", item.getQuantity());
				json.put("currentQuantity", item.getCurrentQuantity());
				json.put("namedListId", namedListId);
				json.put("itemId", item.getId());
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}

	public static JSONObject getJSONAbstract(AbstractObject ao) {
		JSONObject json = new JSONObject();
		if (ao != null) {
			try {
				json.put("id", ao.getId());
				json.put("creationTime", ao.getCreationTime());
				json.put("lastUpdateTime", ao.getLastUpdateTime());
				json.put("deleteFlag", ao.isDeleteFlag());
			} catch (JSONException e) {
				Log.e(TAG, e.getMessage());
			}
		}
		return json;
	}
}
